package com.hlbspringcloud.contentcenter.controller.content;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.hlbspringcloud.contentcenter.domain.dto.uer.UserDTO;
import com.hlbspringcloud.contentcenter.feignclient.TestBaiduFeignClient;
import com.hlbspringcloud.contentcenter.feignclient.TestUserCenterFeignClient;
import com.hlbspringcloud.contentcenter.sentineltest.TestControllerBlockHandlerClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 测试Controller
 * @PROJECT_NAME: spring-cloud-alibaba
 * @CLASS_NAME:
 * @Author: huanglibin
 * @Date: 2020-05-24 17:11
 * @Version: 1.0
 */
@Controller
@RestController
@Slf4j
public class TestController {

    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 测试服务发现:证明内容中心总能找到用户中心
     * @return 用户中心所有实例的地址信息
     */
    @GetMapping("test2")
    public List<ServiceInstance> getInstance(){
        //查询指定服务的所有实例的信息
        return this.discoveryClient.getInstances("user-center");
    }

    @Autowired
    private TestBaiduFeignClient testBaiduFeignClient;

    @GetMapping("baidu")
    public String baiduIndex(){
        return this.testBaiduFeignClient.index();
    }

    @GetMapping("/test-hot")
    @SentinelResource("hot")
    public String testHot(@RequestParam(required = false) String a,@RequestParam(required = false) String b){
        return a+ " " + b;
    }

    @GetMapping("/test-add-flow-rule")
    public String testHot(){
        this.initFlowQpsRule();
        return "success";
    }

    private void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule("/shares/1");
        // set limit qps to 20
        rule.setCount(20);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setLimitApp("default");
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }

//    @GetMapping("/test-sentinel-api")
//    public String testSentinelApi(@RequestParam(required = false) String a){
//        String resourceName = "test-sentinel-api";
//        ContextUtil.enter(resourceName,"test-wfw");
//        //定义一个sentinel保护的资源，名称是test-sentinel-api
//        Entry entry = null;
//        try {
//            entry = SphU.entry(resourceName);
//            //被保护的业务逻辑
//            if (StringUtils.isBlank(a)){
//                throw new IllegalArgumentException("a不能为空");
//            }
//            return "a";
//        }
//        //如果被保护的资源被限流或者降级了，就会抛BlockException
//        catch (BlockException e) {
//            log.warn("限流,或者降级了",e);
//            return "限流,或者降级了";
//        }
//        catch (IllegalArgumentException e2){
//            //统计IllegalArgumentException【发生的次数、发生占比】
//            Tracer.trace(e2);
//            return "参数非法";
//        }
//        finally {
//            if (entry!=null){
//                //退出entry
//                entry.exit();
//            }
//            ContextUtil.exit();
//        }
//    }

    @GetMapping("/test-sentinel-api")
    @SentinelResource(value = "test-sentinel-api"
            ,blockHandlerClass = TestControllerBlockHandlerClass.class
            ,blockHandler = "blockHandler"
            ,fallback = "fallback"
    )
    public String testSentinelApi(@RequestParam(required = false) String a){
        //被保护的业务逻辑
        if (StringUtils.isBlank(a)){
            throw new IllegalArgumentException("a不能为空");
        }
        return a;
    }



    /**
     * 处理降级
     * -- sentinel 1.6 可以处理Throwable
     * @param a
     * @return
     */
    public String fallback(String a){
        log.warn("限流,或者降级了 fallback");
        return "限流,或者降级了 fallback";
    }
}
